package ar.uba.fi.tp2Unit.framework;

import java.util.ArrayList;
import java.util.List;

/**
 * It represents a collection of {@link Test} to be run by a {@link TestRunner}.
 * Each single {@link Test} can be add by calling the {@link #addTest(Test)}.
 * 
 * @author grupo12
 * @see {@link TestCase}, {@link TestRunner}
 */
public class TestSuite extends Test {

	private String name;
	private List<Test> tests;

	public TestSuite(String name) {
		this.name = name;
		this.tests = new ArrayList<Test>();
	}

	public void addTest(Test test) throws TestNameAlreadyExistsException {
		if (!testNameAlreadyExists(test.getName())) {
			test.setTestSuite(this);
			this.tests.add(test);
		} else {
			throw new TestNameAlreadyExistsException(test.getName(), name);
		}
	}

	private boolean testNameAlreadyExists(String testName) {
		for (Test test : tests) {
			if (test.getName().equals(testName)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public void test(TestResult testResult, String pattern,
			TestFixture testFixture) {
		if (matchesPattern(pattern)) {
			for (Test test : tests) {
				setUp(testFixture);
				test.test(testResult, pattern, testFixture);
				tearDown(testFixture);
			}
		}
	}

	public String getSuiteName() {
		if (getTestSuite() != null) {
			return String.format("%s.%s", getTestSuite().getSuiteName(),
					getName());
		}
		return getName();
	}

	@Override
	public String getName() {
		return name;
	}

	@Override
	public void test(TestResult testResult, List<String> runTags,
			TestFixture testFixture) {
		for (Test test : tests) {
			setUp(testFixture);
			test.test(testResult, runTags, testFixture);
			tearDown(testFixture);
		}
	}

	@Override
	public void test(TestResult testResult, String pattern,
			List<String> runTags, TestFixture testFixture) {
		if (matchesPattern(pattern)) {
			for (Test test : tests) {
				setUp(testFixture);
				test.test(testResult, pattern, runTags, testFixture);
				tearDown(testFixture);
			}
		}
	}
}
